package com.example.oauth.secutity.filter;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class SinoAuthenticationProvider implements AuthenticationProvider {
	
	private static final Logger log = LogManager.getLogger();
	
	protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
	
	private UserDetailsService userDetailsService ;
	
	private BCryptPasswordEncoder passwordEncoder;
	
	public SinoAuthenticationProvider(UserDetailsService userDetailsService,BCryptPasswordEncoder passwordEncoder) {
		super();
		this.userDetailsService = userDetailsService;
		this.passwordEncoder = passwordEncoder;
	}
	
	

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username= authentication.getPrincipal().toString();
		if (authentication.getCredentials() == null) {
			log.debug("Authentication failed: no credentials provided");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
		
		UserDetails userDetails = userDetailsService.loadUserByUsername(username);
		String presentedPassword = authentication.getCredentials().toString();

		if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
			log.debug("Authentication failed: password does not match stored value");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
		
		
		SinoAuthenticationToken token = new SinoAuthenticationToken(username,authentication.getCredentials(),userDetails.getAuthorities());
		return token;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return (SinoAuthenticationToken.class
				.isAssignableFrom(authentication));
	}

}
